/**
 * Copyright &copy; 2012-2016 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.jiadakeji.ppm.modules.business.service;

import com.jiadakeji.ppm.common.coderule.CodeRuleFeeReceive;
import com.jiadakeji.ppm.common.coderule.GetCode;
import com.jiadakeji.ppm.common.coderule.GetCodeByRule;
import com.jiadakeji.ppm.common.persistence.Page;
import com.jiadakeji.ppm.common.service.CrudService;
import com.jiadakeji.ppm.common.utils.DateUtils;
import com.jiadakeji.ppm.common.utils.DecimalUtils;
import com.jiadakeji.ppm.modules.business.dao.*;
import com.jiadakeji.ppm.modules.business.entity.*;
import com.jiadakeji.ppm.modules.sys.utils.DictUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.Date;
import java.util.List;

/**
 * 应收台账Service
 * @author HHAOYU
 * @version 2019-07-09
 */
@Service
@Transactional(readOnly = true)
public class FeeChargeService extends CrudService<FeeChargeDao, FeeCharge> {
	@Autowired
	private RoomDao roomDao;
	@Autowired
	private FeeMonthDao feeMonthDao;
	@Autowired
	private CustomerDao customerDao;
	@Autowired
	private FeeReceiveDao feeReceiveDao;

	@Override
	public FeeCharge get(String id) {
		return super.get(id);
	}

	@Override
	public List<FeeCharge> findList(FeeCharge feeCharge) {
		return super.findList(feeCharge);
	}

	@Override
	public Page<FeeCharge> findPage(Page<FeeCharge> page, FeeCharge feeCharge) {
		return super.findPage(page, feeCharge);
	}

	@Override
	@Transactional(readOnly = false)
	public void save(FeeCharge feeCharge) {
		super.save(feeCharge);
	}


	@Override
	@Transactional(readOnly = false)
	public void delete(FeeCharge feeCharge) {
		//TODO 删除其它关联表
		
		super.delete(feeCharge);
	}

	@Transactional(readOnly = false)
	public void initFeecharge(FeeMonth feeMonth) {
		Room room = new Room();
		List<Room> rooms = roomDao.findAllList(room);
		for (Room r:rooms) {
			elecFeeChargeByRoom(r,feeMonth);
		}
	}

	@Transactional(readOnly = false ,rollbackFor = Exception.class)
	public void reCalFeeChargeByRoom(FeeCharge feeCharge){
		FeeCharge fc =  dao.get(feeCharge);
		Room room1 = roomDao.getAll(fc.getRoomId());
		if(fc.getStatus().equals(FeeCharge.STATUS_FINISH)){
			FeeReceive feeReceive = feeReceiveDao.getByChargeId(fc.getId());
		//	if(feeReceive.getType().equals(FeeReceive.TYPE_BALANCE)){
				Room room  = roomDao.get(feeCharge.getRoomId());
				if(null == room){
					System.out.println("这里是异常 快点查原因 + feeReceiveId :"+feeReceive.getId()+"上面没有roomID");
				}else {
					if(null == room.getBalance()){
						room.setBalance(0.0);
					}
					room.setBalance(DecimalUtils.add(room.getBalance(),feeReceive.getPayAmount()));
					room1.setBalance(room.getBalance());
				}
		//	}
			feeReceiveDao.delete(feeReceive);
		}
		FeeMonth feeMonth = feeMonthDao.get(fc.getFeeMonthId());
		elecFeeChargeByRoom(room1,feeMonth);

	}

	@Transactional(readOnly = false ,rollbackFor = Exception.class)
	public void elecFeeChargeByRoom(Room room, FeeMonth feeMonth) {
		FeeCharge feeCharge = new FeeCharge();
		feeCharge.setRoomId(room.getId());
		feeCharge.setFeeMonthId(feeMonth.getId());
		// delete if have currentMonth feeCharge
		int deleteNum = dao.deleteRepeat(feeCharge);
		feeCharge.setRoomUseFlag(room.getUseFlag());
		feeCharge.setAvgElecFee(room.getRoomTypePrice().getAvgElecPrice());
		feeCharge.setAvgWaterFee(room.getRoomTypePrice().getAvgWaterPrice());
		feeCharge.setElevatorFee(room.getRoomTypePrice().getElevatorPrice()==null ? 0.0 : room.getRoomTypePrice().getElevatorPrice());
		feeCharge.setManageFee(DecimalUtils.multiply(room.getRoomTypePrice().getManageFeePrice(),room.getFeeAreaSize()));
		feeCharge.setSecondPushElecFee(room.getRoomTypePrice().getSecondPushElecPrice() == null ? 0.0 :room.getRoomTypePrice().getSecondPushElecPrice());
		if(null != room.getCarList() && !room.getCarList().isEmpty()){
			feeCharge.setCarMonthFee(room.getCarList().stream().filter(car -> car.getStatus().equals(Car.USED)).map(Car::getCarTypePrice).mapToDouble(CarTypePrice::getMonthPrice).sum());
		}else {
			feeCharge.setCarMonthFee(0.0);
		}
		Date nowDate = new Date(System.currentTimeMillis());
		feeCharge.setPublishDate(nowDate);
		LocalDate feebackBeginDate = DateUtils.tranDateToLocalDate(nowDate).plusDays(Integer.valueOf(DictUtils.getDictValue("违约金起收天数","feeback_message","0")));
		feeCharge.setFeebackBeginDate(DateUtils.tranLocalDateToDate(feebackBeginDate));
		feeCharge.setFeebackRate(Double.valueOf(DictUtils.getDictValue("违约金比例","feeback_message","0.0001")));
		feeCharge.setFeebackMoney(0.0);
		feeCharge.setStatus(FeeCharge.STATUS_UNFINISH);
		Double totalFee = 0.0;
		totalFee = DecimalUtils.add(totalFee
				,feeCharge.getAvgElecFee()
				,feeCharge.getAvgWaterFee()
				,feeCharge.getElevatorFee()
				,feeCharge.getManageFee()
				,feeCharge.getSecondPushElecFee()
				,feeCharge.getCarMonthFee());
		feeCharge.setTotalFee(totalFee);
		feeCharge.preInsert();


		if(null != room.getBalance() && DecimalUtils.subtract(room.getBalance(),totalFee)>=0.0){
			room.setBalance(DecimalUtils.subtract(room.getBalance(),totalFee));
			roomDao.update(room);
			feeCharge.setStatus(FeeCharge.STATUS_FINISH);
			FeeReceive feeReceive = new FeeReceive();
			GetCode getCode = new GetCodeByRule(new CodeRuleFeeReceive());
			feeReceive.setCode(getCode.generateCode());
			feeReceive.setPayAmount(feeCharge.getTotalFee());
			feeReceive.setTotalFee(feeCharge.getTotalFee());
			/**
			 * 2为余额收费
			 */
			feeReceive.setType("2");
			feeReceive.setFeeChargeId(feeCharge.getId());
			feeReceive.setFeebackMoney(feeCharge.getFeebackMoney());
			feeReceive.setCashier("1");
			feeReceive.setStatus(FeeReceive.STATUS_PAY_SUCCESS);
			feeReceive.preInsert();
			feeReceiveDao.insert(feeReceive);
		}

		dao.insert(feeCharge);

	}


	@Scheduled(cron = "0 0 1 * * ?")
	@Transactional(readOnly = false ,rollbackFor = Exception.class)
	public void computeFellBack() {
		if("yes".equals(DictUtils.getDictValue("是否收取违约金","fee_back_status",""))){
			FeeCharge feeCharge = new FeeCharge();
			Room room = new Room();
			room.setFeeBackFlag(Room.HAVE_FEEBACK);
			feeCharge.setRoom(room);
			feeCharge.setStatus(FeeCharge.STATUS_UNFINISH);
			List<FeeCharge> feeChargeList = dao.findList(feeCharge);
			for (FeeCharge fc:feeChargeList) {
				if(fc.getFeebackBeginDate().after(new Date(System.currentTimeMillis()))){
					fc.setFeebackMoney(DecimalUtils.add(fc.getFeebackMoney(),DecimalUtils.multiply(fc.getTotalFee(),fc.getFeebackRate())));
					fc.setStatus(FeeCharge.STATUS_TIMEOUT);
				}
				dao.update(fc);
			}
			feeCharge.setStatus(FeeCharge.STATUS_TIMEOUT);
			List<FeeCharge> feeChargeTimeoutList = dao.findList(feeCharge);
			for (FeeCharge fc:feeChargeTimeoutList) {
				fc.setFeebackMoney(DecimalUtils.add(fc.getFeebackMoney(),DecimalUtils.multiply(fc.getTotalFee(),fc.getFeebackRate())));
				dao.update(fc);
			}
		}
	}


}